﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.Common.Math;
using Buddy.CommonBot;
using Buddy.Navigation;
using Buddy.Swtor;
using Buddy.Swtor.Objects;

using WingIt.Routines;
using WingIt.Routines.Mirrors;

using Action = Buddy.BehaviorTree.Action;


namespace WingIt
{
    /// <summary>
    /// <para>CreateBTPS = Create Behavior Tree for PrioritySelector.</para>
    /// <para>All methods in the CreateBTPS class are designed to create Subehaviors that can be included in a PrioritySelector
    /// to accomplish the stated goal.</para>
    /// <para>Notes:<list type="bullet">
    /// <item><description><para> * Using these methods in a <c>BehaviorTree.Sequence</c> will not yield the desired results.</para></description></item>
    /// </list></para>
    /// </summary>
    [RevisionControlId("$Id: Fundamental.cs 684 2012-08-08 10:09:07Z Chinajade $")]
    public static partial class CreateBTPS
    {
        public delegate float       RangeProviderDelegate(object context);
        public delegate string      StringProviderDelegate(object context);

        private static TorPlayer        Me { get { return (BuddyTor.Me); } }
        private static TorCharacter     MyTarget { get { return (TargetSelect.ForAttack()); } }

        /// <summary>
        /// <para>If the CONTRACTREQUIREMENTPREDICATE evaluates to true, the resulting Composite returns <c>RunStatus.Failure</c>
        /// meaning that the PrioritySelector parent should continue with evaluation of its other children.</para>
        /// <para>If the requirement predicate evaluates to false, then a critical contract has been violated.  The information
        /// provided by MESSAGEDELEGATE is then emitted to the log as a 'contract violation'.  Additionally, the Composite returns
        /// <c>RunStatus.Success</c> which will prevent the PrioritySelector parent from evaluating subsequent children.</para>
        /// </summary>
        /// <param name="contractRequirementPredicate"></param>
        /// <param name="messageDelegate"></param>
        /// <returns></returns>
        /// 15Jul2012-23:24UTC chinajade
        public static Composite ContractRequires(Logger.ContractPredicateDelegate contractRequirementPredicate,
                                                 Logger.StringProviderDelegate messageDelegate)
        {
            return (new Decorator(whenContractIsViolated => !contractRequirementPredicate(),
                new Action(logContractViolation => Logger.ContractRequires(contractRequirementPredicate, messageDelegate))
                ));
        }

        public static Composite ReloadWingIt()
        { // Neo93
            return new Decorator(whenSpecChanged => (WingIt.PreviousPrimarySpec != BuddyTor.Me.PrimarySpec()) || (WingIt.PreviousAdvancedClass != BuddyTor.Me.AdvancedClass),
                new Action(handleSpecChange => {
                    Logger.Write("Changed Spec ( old: {0}, new: {1} )", WingIt.PreviousPrimarySpec.ToString(), BuddyTor.Me.PrimarySpec().ToString());
                    WingIt.PreviousPrimarySpec = BuddyTor.Me.PrimarySpec();
                    WingIt.PreviousAdvancedClass = BuddyTor.Me.AdvancedClass;
                    WingIt.Instance.Initialize();
                }));
        }
    }
}
